package models

import (
	"context"
	. "gin-chat/entity"
	"gin-chat/router/request"
	"gorm.io/gorm"
	"time"
)

type _CChatRecordMgr struct {
	*_BaseMgr
}

// CChatRecordMgr open func
func CChatRecordMgr() *_CChatRecordMgr {
	ctx, cancel := context.WithCancel(context.Background())
	return &_CChatRecordMgr{_BaseMgr: &_BaseMgr{DB: db.Table("c_chat_record"), isRelated: globalIsRelated, ctx: ctx, cancel: cancel, timeout: -1}}
}

// GetTableName get sql table name.获取数据库名字
func (obj *_CChatRecordMgr) GetTableName() string {
	return "c_chat_record"
}

// Get 获取
func (obj *_CChatRecordMgr) Get() (result CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Find(&result).Error

	return
}

// Gets 获取批量结果
func (obj *_CChatRecordMgr) Gets() (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Find(&results).Error

	return
}

//////////////////////////option case ////////////////////////////////////////////

// WithID id获取
func (obj *_CChatRecordMgr) WithID(id int) Option {
	return optionFunc(func(o *options) { o.query["id"] = id })
}

// WithSender sender获取
func (obj *_CChatRecordMgr) WithSender(sender int) Option {
	return optionFunc(func(o *options) { o.query["sender"] = sender })
}

// WithRecipient recipient获取
func (obj *_CChatRecordMgr) WithRecipient(recipient int) Option {
	return optionFunc(func(o *options) { o.query["recipient"] = recipient })
}

// WithContent content获取
func (obj *_CChatRecordMgr) WithContent(content string) Option {
	return optionFunc(func(o *options) { o.query["content"] = content })
}

// WithCreateTime create_time获取 创建时间
func (obj *_CChatRecordMgr) WithCreateTime(createTime time.Time) Option {
	return optionFunc(func(o *options) { o.query["create_time"] = createTime })
}

// WithUpdateTime update_time获取 修改时间
func (obj *_CChatRecordMgr) WithUpdateTime(updateTime time.Time) Option {
	return optionFunc(func(o *options) { o.query["update_time"] = updateTime })
}

// GetByOption 功能选项模式获取
func (obj *_CChatRecordMgr) GetByOption(page int, limit int, opts ...Option) (result CChatRecord, err error) {
	options := options{
		query: make(map[string]interface{}, len(opts)),
	}
	for _, o := range opts {
		o.apply(&options)
	}

	err = obj.DB.WithContext(obj.ctx).Scopes(Paginate(page, limit)).Table(obj.GetTableName()).Where(options.query).Find(&result).Error

	return
}

// GetByOptions 批量功能选项模式获取
func (obj *_CChatRecordMgr) GetByOptions(page int, limit int, opts ...Option) (results []*CChatRecord, err error) {
	options := options{
		query: make(map[string]interface{}, len(opts)),
	}
	for _, o := range opts {
		o.apply(&options)
	}

	err = obj.DB.WithContext(obj.ctx).Scopes(Paginate(page, limit)).Table(obj.GetTableName()).Where(options.query).Find(&results).Error

	return
}

//////////////////////////enume case ////////////////////////////////////////////

// GetFromID 通过id获取内容
func (obj *_CChatRecordMgr) GetFromID(id int) (result CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`id` = ?", id).Find(&result).Error

	return
}

// GetBatchFromID 批量查找
func (obj *_CChatRecordMgr) GetBatchFromID(ids []int) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`id` IN (?)", ids).Find(&results).Error

	return
}

// GetFromSender 通过sender获取内容
func (obj *_CChatRecordMgr) GetFromSender(sender int) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`sender` = ?", sender).Find(&results).Error

	return
}

// GetBatchFromSender 批量查找
func (obj *_CChatRecordMgr) GetBatchFromSender(senders []int) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`sender` IN (?)", senders).Find(&results).Error

	return
}

// GetFromRecipient 通过recipient获取内容
func (obj *_CChatRecordMgr) GetFromRecipient(recipient int) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`recipient` = ?", recipient).Find(&results).Error

	return
}

// GetBatchFromRecipient 批量查找
func (obj *_CChatRecordMgr) GetBatchFromRecipient(recipients []int) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`recipient` IN (?)", recipients).Find(&results).Error

	return
}

// GetFromContent 通过content获取内容
func (obj *_CChatRecordMgr) GetFromContent(content string) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`content` = ?", content).Find(&results).Error

	return
}

// GetBatchFromContent 批量查找
func (obj *_CChatRecordMgr) GetBatchFromContent(contents []string) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`content` IN (?)", contents).Find(&results).Error

	return
}

// GetFromCreateTime 通过create_time获取内容 创建时间
func (obj *_CChatRecordMgr) GetFromCreateTime(createTime time.Time) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`create_time` = ?", createTime).Find(&results).Error

	return
}

// GetBatchFromCreateTime 批量查找 创建时间
func (obj *_CChatRecordMgr) GetBatchFromCreateTime(createTimes []time.Time) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`create_time` IN (?)", createTimes).Find(&results).Error

	return
}

// GetFromUpdateTime 通过update_time获取内容 修改时间
func (obj *_CChatRecordMgr) GetFromUpdateTime(updateTime time.Time) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`update_time` = ?", updateTime).Find(&results).Error

	return
}

// GetBatchFromUpdateTime 批量查找 修改时间
func (obj *_CChatRecordMgr) GetBatchFromUpdateTime(updateTimes []time.Time) (results []*CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`update_time` IN (?)", updateTimes).Find(&results).Error

	return
}

//////////////////////////primary index case ////////////////////////////////////////////

// FetchByPrimaryKey primay or index 获取唯一内容
func (obj *_CChatRecordMgr) FetchByPrimaryKey(id int) (result CChatRecord, err error) {
	err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`id` = ?", id).Find(&result).Error

	return
}

func (obj *_CChatRecordMgr) ChatRecordPage(params *request.ChatRecordPageRequest) (results []*CChatRecord, err error) {
	page := params.Page
	limit := params.Limit

	err = obj.DB.WithContext(obj.ctx).Scopes(Paginate(page, limit)).
		Table(obj.GetTableName()).
		Where("sender = ? and recipient = ?", params.Sender, params.Recipient).
		Or("sender = ? and recipient = ?", params.Recipient, params.Sender).
		Order("id desc").
		Find(&results).Error

	return
}

func Paginate(page int, limit int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if page == 0 {
			page = 1
		}

		switch {
		case limit > 100:
			limit = 100
		case limit <= 0:
			limit = 10
		}

		offset := (page - 1) * limit
		return db.Offset(offset).Limit(limit)
	}
}
